package com.shire.shire_interface.service.commandcenter.queues;

import com.alibaba.fastjson.JSONObject;
import com.shire.shire_interface.common.utils.RandomGen;
import com.shire.shire_interface.constants.Constants;
import com.shire.shire_interface.constants.WxConstants;
import com.shire.shire_interface.model.command.WxCommand;
import com.shire.shire_interface.model.cs.WxChat;
import com.shire.shire_interface.model.friend.WxFriendLog;
import com.shire.shire_interface.model.group.WxGroup;
import com.shire.shire_interface.model.marketing.WxGroupTask;
import com.shire.shire_interface.model.marketing.WxGroupTaskExample;
import com.shire.shire_interface.model.marketing.WxGroupTaskItem;
import com.shire.shire_interface.model.marketing.WxGroupTaskItemExample;
import com.shire.shire_interface.model.user.WxAccount;
import com.shire.shire_interface.service.chat.WxChatService;
import com.shire.shire_interface.service.commandcenter.WxCommandService;
import com.shire.shire_interface.service.friend.WxFriendLogService;
import com.shire.shire_interface.service.group.WxGroupMemberService;
import com.shire.shire_interface.service.group.WxGroupService;
import com.shire.shire_interface.service.marketing.WxGroupTaskItemService;
import com.shire.shire_interface.service.marketing.WxGroupTaskService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class JoinGroupCommandQueue extends GappedCommandQueue {
    private static Logger logger = LoggerFactory.getLogger(JoinGroupCommandQueue.class);
    @Resource
    private WxCommandService commandService;
    @Resource
    private WxFriendLogService friendLogService;
    @Resource
    private WxGroupTaskService taskService;
    @Resource
    private WxGroupTaskItemService taskItemService;
    @Resource
    private WxGroupService groupService;
    @Resource
    private WxGroupMemberService groupMemberService;
    @Resource
    private WxChatService chatService;

    private static JoinGroupCommandQueue instance;

    @PostConstruct
    public void init() {
        instance = this;
    }

    public static JoinGroupCommandQueue getInstance() {
        return instance;
    }

    public JoinGroupCommandQueue getQueueForAccount(WxAccount account) {
        return new JoinGroupCommandQueue(account, queuePriority, commandService, friendLogService, taskService, taskItemService, groupService, groupMemberService, chatService);
    }

    public JoinGroupCommandQueue() {
        super();
    }

    public JoinGroupCommandQueue(WxAccount wxAccount,
                                 WxConstants.CmdPriority priority,
                                 WxCommandService commandService,
                                 WxFriendLogService friendLogService,
                                 WxGroupTaskService groupTaskService,
                                 WxGroupTaskItemService groupTaskItemService,
                                 WxGroupService groupService,
                                 WxGroupMemberService groupMemberService,
                                 WxChatService chatService) {
        super(wxAccount, priority);
        this.commandService = commandService;
        this.friendLogService = friendLogService;
        this.taskService = groupTaskService;
        this.taskItemService = groupTaskItemService;
        this.groupService = groupService;
        this.groupMemberService = groupMemberService;
        this.chatService = chatService;
    }

    @Override
    public WxCommand getNextCommand() {
        //每五分钟执行一次

        if (lastReturnTime != null && (new Date()).getTime() - lastReturnTime.getTime() < 2 * 60 * 1000)
            return null;
        curCmd = null;
        //是否有任务
        WxGroupTaskExample taskExample = new WxGroupTaskExample();
        taskExample.createCriteria().andManageaccountsLike("%" + wxAccount.getWxid() + "%").andStatusEqualTo(Constants.YesNo.YES.getCode());
        List<WxGroupTask> groupTasks = taskService.selectByExample(taskExample);

        if (groupTasks.size() < 1)
            return null;
        for (WxGroupTask task : groupTasks) {
            WxGroupTaskItemExample taskItemExample = new WxGroupTaskItemExample();
            taskItemExample.createCriteria().andTaskidEqualTo(task.getId());
            taskItemExample.setOrderByClause("roleType asc");
            List<WxGroupTaskItem> itemList = taskItemService.selectByExample(taskItemExample);
            WxCommand cmd = null;
            if (task.getAccountwxid().equals(wxAccount.getWxid())) {
                //主帐号
                //如果有待加好友就加好友
                if (getAddFriendCmd(task, itemList, cmd)){
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
                if (createGroup(task, itemList)){
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
                //有群就加群
                if (inviteToGroup(task, itemList)) {
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
            } else {
                //辅助助号
                //加好友
                if (getAddFriendCmd(task, itemList, cmd)) {
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
                //拉群
                if (inviteToGroup(task, itemList)) {
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
                if (task.getTasktype() == 0 && (task.getFinishcount()>=task.getMembercount() || task.getStatus() == 2)){
                    //讨论组， 达到人数或手动设置为完成
                    WxGroup group = groupService.selectGroupByNoForCs(wxAccount.getCsid(),wxAccount.getWxid(),task.getGroupno());
                    WxChat chat = chatService.genNoticeChat(-1l, RandomGen.getRandomString(20), group,
                            task.getMsgcontent(), wxAccount.getCsid());
                    chatService.sendChatByCmd(chat);
                    task.setTaskstatus(2);
                    task.setUpdatetime(new Date());
                    taskService.updateByPrimaryKeySelective(task);
                    lastReturnTime = new Date();
                    return super.getNextCommand();
                }
            }
        }

        //是否满足人数 是：拉群 否：加人，如果都加了就等试下一个任务
        lastReturnTime = new Date();
        return super.getNextCommand();
    }

    private boolean createGroup(WxGroupTask task, List<WxGroupTaskItem> itemList) {
        if(task.getGroupcmdid()!=null){
            return false;
        }
        List<String> memList = new ArrayList<>();
        memList.add(wxAccount.getWxid());
        int p = 0;
        for (WxGroupTaskItem wxGroupTaskItem : itemList) {
            if (wxGroupTaskItem.getWxaccount().equals(wxAccount.getWxid()) && wxGroupTaskItem.getCurstep() == 1) {
                memList.add(wxGroupTaskItem.getWxid());
                p++;
                if (p >= task.getBatchnum())
                    break;
            }
        }

        if (memList.size() < 3) {
            return false;
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", task.getGroupname());
        jsonObject.put("wxIds", String.join(",", memList));
        curCmd = commandService.generateCmdObject(wxAccount.getCsid(),
                wxAccount.getId(),
                jsonObject.toJSONString(),
                WxConstants.CmdTaskType.JOINGROUP,
                task.getId(),
                WxConstants.CmdType.CRK_CREATE_GROUP_D,
                WxConstants.CmdPriority.JOINGROUP);
        task.setGroupcmdid(curCmd.getId().intValue());
        task.setGroupcmdstatus(curCmd.getRststatus());
        task.setUpdatetime(new Date());
        task.setFinishcount(memList.size());
        task.setSendcount(memList.size()-1); //已邀请人数，不包括群主
        taskService.updateByPrimaryKeySelective(task);

        WxGroupTaskItemExample example = new WxGroupTaskItemExample();
        example.createCriteria().andTaskidEqualTo(task.getId()).andWxaccountEqualTo(wxAccount.getWxid()).andWxidIn(memList);
        WxGroupTaskItem item = new WxGroupTaskItem();
        item.setCurstep(2);
        item.setUpdatetime(new Date());
        item.setJoincmdid(curCmd.getId().intValue());
        item.setJoinrststatus(curCmd.getRststatus());
        item.setGroupinvitetime(new Date());
        taskItemService.updateByExample(item, example);

        return true;
    }

    private boolean getAddFriendCmd(WxGroupTask task, List<WxGroupTaskItem> itemList, WxCommand cmd) {
        for (WxGroupTaskItem wxGroupTaskItem : itemList) {
            if (wxGroupTaskItem.getCurstep() > 0)
                continue;
            if (wxGroupTaskItem.getWxaccount().equals(wxAccount.getWxid())) {
                if ((wxGroupTaskItem.getInvitecmdid() == null|| wxGroupTaskItem.getInvitecmdid()<1) && wxGroupTaskItem.getMembertype() == 0) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("wxId", wxGroupTaskItem.getSearchname());
                    jsonObject.put("message", task.getApplymsg());
                    cmd = commandService.generateCmdObject(wxAccount.getCsid(),
                            wxAccount.getId(),
                            jsonObject.toJSONString(),
                            WxConstants.CmdTaskType.JOINGROUP,
                            wxGroupTaskItem.getId(),
                            WxConstants.CmdType.CRK_ADD_WXID,
                            WxConstants.CmdPriority.INVITE);
                    WxFriendLog friendLog = new WxFriendLog();
                    friendLog.setAddtype(WxConstants.FriendAddType.FROMSEARCH.getCode());
                    friendLog.setRststatus(cmd.getRststatus());
                    friendLog.setApplymsg(task.getApplymsg());
                    friendLog.setCmdid(cmd.getId());
                    friendLog.setCmdtype(WxConstants.CmdType.CRK_ADD_WXID.getCode());
                    friendLog.setCreatetime(new Date());
                    friendLog.setCsid(wxAccount.getCsid());
                    friendLog.setKeyword(wxGroupTaskItem.getSearchname());
                    friendLog.setTasktype(WxConstants.CmdTaskType.JOINGROUP.getCode());
                    friendLog.setTaskid(wxGroupTaskItem.getId());
                    friendLogService.inserFriendLog(friendLog);
                }

                //待加群好友
                if ((wxGroupTaskItem.getInvitecmdid() == null || wxGroupTaskItem.getInvitecmdid()<1) && wxGroupTaskItem.getMembertype() == 2) {
                    cmd = commandService.getAddGroupMemberCmd(wxAccount,
                            wxGroupTaskItem.getGroupno(),
                            wxGroupTaskItem.getWxid(),
                            task.getApplymsg(),
                            WxConstants.CmdTaskType.JOINGROUP,
                            wxGroupTaskItem.getId());
                }

                if (wxGroupTaskItem.getInvitecmdid() != null) {
                    if (wxGroupTaskItem.getInvitetime()!=null && (new Date()).getTime() - wxGroupTaskItem.getInvitetime().getTime() > 1000 * 60 * 60 * 48) {
                        wxGroupTaskItem.setUpdatetime(new Date());
                        wxGroupTaskItem.setCurstep(4);
                        taskItemService.updateByPrimaryKey(wxGroupTaskItem);
                        continue;
                    }
                }

                if (cmd == null)
                    continue;

                wxGroupTaskItem.setInvitecmdid(cmd.getId().intValue());
                wxGroupTaskItem.setInviterststatus(cmd.getRststatus());
                wxGroupTaskItem.setUpdatetime(new Date());
                wxGroupTaskItem.setInvitetime(new Date());

                taskItemService.updateByPrimaryKey(wxGroupTaskItem);
                if (cmd != null) {
                    curCmd = cmd;
                    return true;
                }
            }
        }
        return false;
    }

    private boolean inviteToGroup(WxGroupTask task, List<WxGroupTaskItem> itemList) {
        if (task.getGroupno() == null)
            return false;
        List<String> wxIdList = new ArrayList<>();
        int p = 0;
        for (WxGroupTaskItem wxGroupTaskItem : itemList) {
            if (wxGroupTaskItem.getWxaccount().equals(wxAccount.getWxid())
                    && wxGroupTaskItem.getCurstep() == 1
                    && StringUtils.isNotBlank(wxGroupTaskItem.getWxid())
                    && wxGroupTaskItem.getJoincmdid() == null) {

                if (p >= task.getBatchnum()) {
                    break;
                }
                if (task.getTasktype() == 0) {
                    //讨论组
                    if (task.getFinishcount() + p >= 39 || task.getFinishcount() + p >= task.getMembercount()) {
                        break;
                    }
                }
                wxIdList.add(wxGroupTaskItem.getWxid());
                p++;
            }
        }

        if (wxIdList.size() > 0 && task.getFinishcount() <= task.getMembercount()) {
            if (wxIdList.size() > (task.getMembercount() + 1 - task.getFinishcount())) { //finishcount 包括群主
                wxIdList = wxIdList.subList(0, (task.getMembercount() - task.getFinishcount()));
            }
            if (wxIdList.isEmpty())
                return true;
            String memIds = String.join(",", wxIdList);
            JSONObject reqJSON = new JSONObject();
            reqJSON.put("userWxIds", memIds);
            reqJSON.put("groupWxId", task.getGroupno());
            curCmd = commandService.generateCmdObject(wxAccount.getCsid(),
                    wxAccount.getId(),
                    reqJSON.toJSONString(),
                    WxConstants.CmdTaskType.JOINGROUP,
                    task.getId(),
                    WxConstants.CmdType.CRK_INVITE_GROUP_D,
                    WxConstants.CmdPriority.JOINGROUP);

            WxGroupTaskItemExample example = new WxGroupTaskItemExample();
            example.createCriteria().andTaskidEqualTo(task.getId()).andWxaccountEqualTo(wxAccount.getWxid()).andWxidIn(wxIdList);
            WxGroupTaskItem item = new WxGroupTaskItem();
            item.setCurstep(2);
            item.setUpdatetime(new Date());
            item.setJoincmdid(curCmd.getId().intValue());
            item.setJoinrststatus(curCmd.getRststatus());
            item.setGroupinvitetime(new Date());
            taskItemService.updateByExample(item, example);

            task.setSendcount(task.getSendcount() + wxIdList.size());
            task.setUpdatetime(new Date());
            taskService.updateByPrimaryKeySelective(task);

            return true;
        }
        return false;
    }

}
